4.1 什么是类型?

一切皆是映射

在计算机中,任何数值都是以一组比特(01)组成的,硬件无法区分内存地址、脚本、字符、整数、以及浮点数。这个时候,我们使用类型赋予一组比特以特定的意义。

类型(Type),本质上就是内存中的数值或变量对象的逻辑映射。

《周易》有云:

易有太极,是生两仪,两仪生四象,四象生八卦。(《易传·系辞上传》) 。

这里所包含的思想,跟我们这里所说的类型系统的思想有着异曲同工之妙。

类型系统用于定义如何将编程语言中的数值和表达式归类为许多不同的类型,如何操作这些类型,这些类型如何互相作用等。

类型系统在各种语言之间有非常大的不同,主要的差异存在于编译时期的语法,以及运行时期的操作实现方式。

类型系统提供的主要功能有:

  • 安全性

编译器可以使用类型来检查无意义的,或者是可能无效的代码。例如,在强类型的语言中,如果没有对字符串的+进行重载,那么表达式

  1. "Hello, World" + 3

就会被编译器检测出来,因为不能对字符串加上一个整数。强类型提供更多的安全性。

但是,为了让程序员可以写出极简的代码,很多语言都提供了操作符重载的机制。比如说,在Scala中,上面的代码是可以被正确执行的(重载了+操作符)

  1. scala> "Hello,World"+1
  2. res15: String = Hello,World1
  3. scala> 1+"Hello,World"
  4. res16: String = 1Hello,World

但是在Kotlin中, 由于Int类型没有对+实现重载,所以情况是这样

  1. >>> "Hello,World"+1
  2. Hello,World1
  3. >>> 1+"Hello,World"
  4. error: none of the following functions can be called with the arguments supplied:
  5. public final operator fun plus(other: Byte): Int defined in kotlin.Int
  6. public final operator fun plus(other: Double): Double defined in kotlin.Int
  7. public final operator fun plus(other: Float): Float defined in kotlin.Int
  8. public final operator fun plus(other: Int): Int defined in kotlin.Int
  9. public final operator fun plus(other: Long): Long defined in kotlin.Int
  10. public final operator fun plus(other: Short): Int defined in kotlin.Int
  11. 1+"Hello,World"
  12. ^
  • 最优化

静态类型检查可提供有用的信息给编译器。编译器可以使用更有效率的机器指令,实现编译器优化。

  • 可读性

  • 抽象化(或模块化)

类型本质上是对较低层次的逻辑单元进行高层次的逻辑抽象。这样我们就可以直接使用类型在较高层次的方式思考,而不是繁重的低层次实现。

例如,我们可以将字符串想成一个值,以此取代仅仅是字节的数组。字符串就是一个抽象数据类型。

从01到类型,从类型到接口API,再到软件服务,都可以看做是广义的“类型”范畴。

程序中的变量在程序执行期间,可能会有不同的取值范围,我们可以把变量可取值的最大范围称为这个变量的类型。例如,具有类型Boolean的变量x,在程序执行期间,只能取布尔值。指定变量类型的程序设计语言,称为类型化的语言(typed language)。

如果一个语言,不限制变量的取值,称为无类型语言(untyped language),我们既可以说它不具有类型,也可以说它具有一个通用类型,这个类型的取值范围是程序中所有可能的值。

类型系统是类型化语言的一个组成部分,它用来计算和跟踪程序中所有表达式的类型,从而判断某段程序是否表现良好(well behaved)。

如果程序语言的语法中含有类型标记,就称该语言是显式类型化的(explicitly typed),否则就称为隐式类型化的(implicitly typed)。

像C、C++、Java等语言,都是显式类型化的。而像ML、Haskell、Groovy等可以省略类型声明,它们的类型系统会自动推断出程序的类型。